package cc.rengu.redp.bizimpl.igas.controller;


import cc.rengu.redp.bizimpl.igas.domain.SDevBindInfo;
import cc.rengu.redp.bizimpl.igas.domain.SMchntBindInfo;
import cc.rengu.redp.bizimpl.igas.service.ISDevBindInfoService;
import cc.rengu.redp.bizimpl.igas.vo.SDevBindInfoVO;
import cc.rengu.redp.common.annotation.Log;
import cc.rengu.redp.common.controller.BaseController;
import cc.rengu.redp.common.domain.QueryRequest;
import cc.rengu.redp.common.domain.RedpResponse;
import cc.rengu.redp.common.exception.RedpException;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.wuwenze.poi.ExcelKit;
import com.wuwenze.poi.handler.ExcelReadHandler;
import com.wuwenze.poi.pojo.ExcelErrorField;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;

/**
 * @author lizk
 */
@RestController
@RequestMapping("devBindInfo")
@Slf4j
public class SDevBindInfoController extends BaseController {

    @Autowired
    private ISDevBindInfoService isDevBindInfoService;

    @GetMapping
    public Map<String, Object> findByPage(QueryRequest queryRequest, SDevBindInfo sDevBindInfo){
        return getDataTable(isDevBindInfoService.findByPage(queryRequest, sDevBindInfo));
    }

    @GetMapping("findBindUserId")
    public List<SMchntBindInfo> findBindUserId(@RequestParam("bindMchntNo") String bindMchntNo){
        return isDevBindInfoService.findBindUserId(bindMchntNo);
    }

    @Log("新增语音设备信息")
    @PostMapping
    public void addBindInfo(@Valid SDevBindInfo sDevBindInfo) throws RedpException {
        try {
            this.isDevBindInfoService.createInfo(sDevBindInfo);
        } catch (Exception e) {
            String message = "新增语音设备信息失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @Log("修改语音设备信息")
    @PutMapping
//    @RequiresPermissions("brand:update")
    public void updateBindInfo(SDevBindInfo sDevBindInfo) throws RedpException {
        try {
            this.isDevBindInfoService.updateInfo(sDevBindInfo);
        } catch (Exception e) {
            String message = "修改语音设备信息失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @Log("语音设备信息注销")
    @PutMapping("bindInfoCancel")
    public void bindInfoCancel(SDevBindInfo sDevBindInfo) throws RedpException {
        try {
            this.isDevBindInfoService.updateDevBindInfoStatus(sDevBindInfo);
        } catch (Exception e) {
            String message = "语音设备信息注销失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @Log("语音设备信息停用")
    @PutMapping("bindInfoStop")
    public void bindInfoStop(SDevBindInfo sDevBindInfo) throws RedpException {
        try {
            this.isDevBindInfoService.updateDevBindInfoStatus(sDevBindInfo);
        } catch (Exception e) {
            String message = "语音设备信息停用失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @Log("语音设备信息启用")
    @PutMapping("bindInfoUse")
    public void bindInfoUse(SDevBindInfo sDevBindInfo) throws RedpException {
        try {
            this.isDevBindInfoService.updateDevBindInfoStatus(sDevBindInfo);
        } catch (Exception e) {
            String message = "语音设备信息启用失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }
    @Log("语音设备信息绑定")
    @PutMapping("bindInfoBind")
    public void bindInfoBind(SDevBindInfo sDevBindInfo) throws RedpException {
        try {
            this.isDevBindInfoService.updateDevBindInfoStatus(sDevBindInfo);
        } catch (Exception e) {
            String message = "语音设备信息绑定失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }
    @Log("语音设备信息解绑")
    @PutMapping("bindInfoUnbind")
    public void bindInfoUnbind(SDevBindInfo sDevBindInfo) throws RedpException {
        try {
            this.isDevBindInfoService.updateDevBindInfoStatus(sDevBindInfo);
        } catch (Exception e) {
            String message = "语音设备信息解绑失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    /**
     * 生成 Excel导入模板
     */
    @PostMapping("downloadTemplate")
    public void generateImportTemplate(HttpServletResponse response) {
        // 构建数据
        List<SDevBindInfoVO> list = new ArrayList<>();
        IntStream.range(0, 1).forEach(i -> {
            SDevBindInfoVO sDevBindInfo = new SDevBindInfoVO();
            sDevBindInfo.setBindDevId("MU00004");
            sDevBindInfo.setBindDevModel("Echo智能语音设备");
            sDevBindInfo.setBindDevBrand("Echo-002");
            list.add(sDevBindInfo);
        });
        // 构建模板
        ExcelKit.$Export(SDevBindInfoVO.class, response).downXlsx(list, true);
    }


    /**
     * 导入Excel数据，并批量插入 T_TEST表
     */
    @PostMapping("import")
    public RedpResponse importExcels(@RequestParam("file") MultipartFile file, @RequestParam("instId") String instId,
            @RequestParam("msgPushKey") String msgPushKey) throws RedpException {
        try {
            if (file.isEmpty()) {
                throw new RedpException("导入数据为空");
            }
            String filename = file.getOriginalFilename();
            if (!StringUtils.endsWith(filename, ".xlsx")) {
                throw new RedpException("只支持.xlsx类型文件导入");
            }
            // 开始导入操作
            long beginTimeMillis = System.currentTimeMillis();
            final List<SDevBindInfoVO> data = Lists.newArrayList();
            final List<Map<String, Object>> error = Lists.newArrayList();
            ExcelKit.$Import(SDevBindInfoVO.class).readXlsx(file.getInputStream(), new ExcelReadHandler<SDevBindInfoVO>() {
                @Override
                public void onSuccess(int sheet, int row, SDevBindInfoVO test) {
                    //先判断品牌名称存不存在
                    boolean result = isDevBindInfoService.isExit(test.getBindDevId());
                    List<ExcelErrorField> list = new ArrayList<>();
                    if (result){//不存在
                        // 数据校验成功时，加入集合
                        test.setInstId(instId);
                        test.setMsgPushKey(msgPushKey);
                        data.add(test);
                    }else {
                        //把品牌名称重复的放置到错误信息里面
                        list.add(new ExcelErrorField(0,test.getBindDevId(),"绑定设备编码","绑定设备编码已存在，请修改再试"));
                        error.add(ImmutableMap.of("row", row, "errorFields", list));
                    }

                }

                @Override
                public void onError(int sheet, int row, List<ExcelErrorField> errorFields) {
                    // 数据校验失败时，记录到 error集合
                    error.add(ImmutableMap.of("row", row, "errorFields", errorFields));
                }
            });
            if (!data.isEmpty()) {
                // 将合法的记录批量入库
                this.isDevBindInfoService.batchInsert(data);
            }
            long time = ((System.currentTimeMillis() - beginTimeMillis));
            ImmutableMap<String, Object> result = ImmutableMap.of(
                    "time", time,
                    "data", data,
                    "error", error
            );
            return new RedpResponse().data(result);
        } catch (Exception e) {
            String message = "导入Excel数据失败," + e.getMessage();
            log.error(message);
            throw new RedpException(message);
        }
    }


}
